package com.smart.wap.service;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.smart.common.exception.SmartException;
import com.smart.manager.finance.entities.models.FinanceAccountAlipay;
import com.smart.manager.finance.repository.AccountAlipayRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;


/**
 * 微信支付处理程序
 *
 * @author xiaxuqiu
 * @date 2022/10/27
 */
@Service
@Log4j2
@RequiredArgsConstructor

public class AliPayHandler {


    private final AccountAlipayRepository accountAlipayRepository;


    /**
     * @param accountAlipay 获取支付宝支付配置文件
     * @return {@code AlipayConfig}
     */
    public AlipayConfig getAlipayConfig(FinanceAccountAlipay accountAlipay) {
        String gateWay = accountAlipay.getSandbox() ? "https://openapi.alipaydev.com/gateway.do" : "https://openapi.alipay.com/gateway.do";
        Assert.notNull(accountAlipay, "没有找到相关的APPID参数");
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(gateWay);
        alipayConfig.setAppId(accountAlipay.getAppId());
        alipayConfig.setPrivateKey(accountAlipay.getPrivateKey());
        alipayConfig.setAlipayPublicKey(accountAlipay.getPublicKey());
        alipayConfig.setSignType(accountAlipay.getSignType());
        return alipayConfig;
    }


    /**
     * @param appId 应用ID
     * @return {@code DefaultAlipayClient}
     */
    public DefaultAlipayClient getAlipayClient( String appId) {
        try {
            FinanceAccountAlipay accountAlipay = accountAlipayRepository.getOneById(appId);
            AlipayConfig alipayConfig = getAlipayConfig(accountAlipay);
            return new DefaultAlipayClient(alipayConfig);
        } catch (AlipayApiException exception) {
            throw new SmartException("支付宝配置信息出错:" + exception.getMessage());
        }

    }


    /**
     * 支付宝支付处理程序
     *
     * @param notifyUrl 通知地址
     * @param orderId   订单编号
     * @param fee       订单金额
     * @param attach    附加数据
     * @return {@code String}
     */

    public String pushCoinOrderToAlipay(String appId , String orderId, BigDecimal fee, String notifyUrl, String attach) {
        try {
            JSONObject bizContent = JSONObject.of("out_trade_no", orderId, "total_amount", fee, "subject", attach);
            AlipayClient alipayClient = getAlipayClient(appId);
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            request.setBizContent(bizContent.toJSONString());
            request.setNotifyUrl(notifyUrl);
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            if (response.isSuccess()) {
                return response.getBody();
            }
            throw new RuntimeException("支付宝订单创建失败:" + response.getMsg());
        } catch (AlipayApiException e) {
            throw new SmartException("支付宝订单创建失败:" + e.getMessage());

        }

    }


    /**
     * @param map  验签Map
     * @return boolean 签名验证结果
     */
    public boolean checkSign(Map<String, String> map) {
        try {
            String appId = map.get("app_id");
            String sign = map.get("sign");
            FinanceAccountAlipay accountAlipay = accountAlipayRepository.getOneById(appId);
            AlipayConfig alipayConfig = getAlipayConfig(accountAlipay);
            String content = AlipaySignature.getSignCheckContentV1(map);
            return AlipaySignature.rsaCheck(content, sign, alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());
        } catch (AlipayApiException e) {
            throw new SmartException("支付宝请回调验签失败: " + e.getMessage());
        }
    }
}